#ifndef __VFS_H__
#define __VFS_H__
#include "libs/types.h"
#include "libs/lib.h"


class Indexnode;
class DirEntry;
class File;
class SuperBlock;







class IndexNode
{
private:
    /* data */
public:
    uint64_t fileSize;
    uint64_t blocks;
    uint64_t attribute;
    SuperBlock* sb;
    
    void* privateIndexInfo;
    IndexNode(/* args */);
    ~IndexNode();
	virtual DirEntry* create(DirEntry* dentry,char* name,uint64_t attribute);
	virtual DirEntry* lookup(IndexNode * parent_inode,DirEntry * dest_dentry);
	// virtual long mkdir(IndexNode * inode,DirEntry * dentry,int32_t mode);
	// virtual long rmdir(IndexNode * inode,DirEntry * dentry);
	// virtual long rename(IndexNode * old_inode,DirEntry * old_dentry,IndexNode * new_inode,DirEntry * new_dentry);
	// virtual long getattr(DirEntry * dentry,unsigned long * attr);
	// virtual long setattr(DirEntry * dentry,unsigned long * attr);

};

class SuperBlock
{
private:
    /* data */
public:
    DirEntry* root;
    void* privateSbInfo;
    SuperBlock(/* args */);
    ~SuperBlock();
    virtual void writeInode(IndexNode* inode);
};

#define FS_ATTR_FILE	(1UL << 0)
#define FS_ATTR_DIR		(1UL << 1)
#define	FS_ATTR_DEVICE	(1UL << 2)


class DirEntry
{
private:
    /* data */
public:
    char* name;
    int32_t nameLength;
    IndexNode* dirInode;
    DirEntry* parent;
    List childNode;
    List subdirsList;
    
    DirEntry(/* args */);
    ~DirEntry();

//    virtual  int64_t compare(DirEntry* parentDentry,char* sourceFilename,char* destinationFilename);
//    virtual int64_t hash(DirEntry* dentry,char* filename);
//    virtual int64_t release(DirEntry* dentry);
//    virtual int64_t iput(DirEntry* dentry,IndexNode* inode);
};




class File
{
private:
    /* data */
public:
    int64_t position;
    uint64_t mode;
    DirEntry* dentry;
    void* privateData;
    File(/* args */);
    ~File();

   virtual int64_t open(IndexNode* inode,File* filp);
   virtual int64_t close(IndexNode* inode,File* filp);
   virtual int64_t read(char* buf, uint64_t count,int64_t* position);
   virtual int64_t write(char* buf, uint64_t count,int64_t* position);
   virtual int64_t lseek(int64_t offset, int64_t origin);
   virtual int64_t ioctl(IndexNode* inode,File* filp,uint64_t cmd,uint64_t arg);
};




class FileSystem
{
private:
    /* data */
public:
    char* name;
    FileSystem* next;
    uint64_t fsFlag;
    FileSystem(/* args */);
    ~FileSystem();
    virtual SuperBlock* readSuperBlock(void* buf);
};



class VFS
{
private:
    /* data */
public:
    static VFS* vfsm;
    FileSystem fileSystem;
    VFS(/* args */);
    ~VFS();

    SuperBlock* mountFs(char* name,void* buf);
    uint64_t addFilesystem(FileSystem* fs);
};




#define VFSMANAGER \
VFS::vfsm







#endif